1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use core::ffi::{c_uchar, c_uint, c_ulong};

///This is the struct to interact in a save way with the ArduboyTones C++ library.
///
/// You will need to uncomment the ArduboyTones in the config.toml file.

pub struct ArduboyTones {}
impl ArduboyTones {
    ///Get a new instance of [ArduboyTones]
    /// ## Example
    /// ```
    /// use arduboy_rust::prelude::*;
    /// #[allow(non_upper_case_globals)]
    /// const sound: ArduboyTones = ArduboyTones::new();
    /// ```
    pub const fn new() -> ArduboyTones {
        ArduboyTones {}
    }
    ///Play a single tone.
    ///
    ///- freq The frequency of the tone, in hertz.
    ///- dur The duration to play the tone for, in 1024ths of a
    ///second (very close to milliseconds). A duration of 0, or if not provided,
    ///means play forever, or until `noTone()` is called or a new tone or
    ///sequence is started.
    pub fn tone(&self, frequency: u16, duration: u32) {
        unsafe { sound_tone(frequency, duration) }
    }
    /// Play two tones in sequence.
    ///
    /// - freq1,freq2 The frequency of the tone in hertz.
    /// - dur1,dur2 The duration to play the tone for, in 1024ths of a
    /// second (very close to milliseconds).
    pub fn tone2(&self, frequency1: u16, duration1: u32, frequency2: u16, duration2: u32) {
        unsafe { sound_tone2(frequency1, duration1, frequency2, duration2) }
    }
    /// Play three tones in sequence.
    ///
    /// - freq1,freq2,freq3 The frequency of the tone, in hertz.
    /// - dur1,dur2,dur3 The duration to play the tone for, in 1024ths of a
    /// second (very close to milliseconds).
    pub fn tone3(
        &self,
        frequency1: u16,
        duration1: u32,
        frequency2: u16,
        duration2: u32,
        frequency3: u16,
        duration3: u32,
    ) {
        unsafe {
            sound_tone3(
                frequency1, duration1, frequency2, duration2, frequency3, duration3,
            )
        }
    }
    /// Play a tone sequence from frequency/duration pairs in a PROGMEM array.
    ///
    /// - tones A pointer to an array of frequency/duration pairs.
    ///
    /// The array must be placed in code space using `PROGMEM`.
    ///
    /// See the `tone()` function for details on the frequency and duration values.
    /// A frequency of 0 for any tone means silence (a musical rest).
    ///
    /// The last element of the array must be `TONES_END` or `TONES_REPEAT`.
    ///
    /// Example:
    /// ```
    /// use arduboy_rust::prelude::*;
    /// #[allow(non_upper_case_globals)]
    /// const sound: ArduboyTones = ArduboyTones::new();
    /// progmem!(
    ///     static sound1: [u8; _] = [220, 1000, 0, 250, 440, 500, 880, 2000, TONES_END];
    /// );
    ///
    /// sound.tones(get_tones_addr!(sound1));
    /// ```
    pub fn tones(&self, tones: *const u16) {
        unsafe { sound_tones(tones) }
    }
    /// Stop playing the tone or sequence.
    ///
    /// If a tone or sequence is playing, it will stop. If nothing
    /// is playing, this function will do nothing.
    pub fn no_tone(&self) {
        unsafe { sound_no_tone() }
    }
    /// Check if a tone or tone sequence is playing.
    ///
    /// - return boolean `true` if playing (even if sound is muted).
    pub fn playing(&self) -> bool {
        unsafe { sound_playing() }
    }
    /// Play a tone sequence from frequency/duration pairs in an array in RAM.
    ///
    /// - tones A pointer to an array of frequency/duration pairs.
    ///
    /// The array must be located in RAM.
    ///
    /// See the `tone()` function for details on the frequency and duration values.
    /// A frequency of 0 for any tone means silence (a musical rest).
    ///
    /// The last element of the array must be `TONES_END` or `TONES_REPEAT`.
    ///
    /// Example:
    ///
    /// ```
    /// use arduboy_rust::prelude::*;
    /// use tones_pitch::*;
    /// let sound2: [u16; 9] = [220, 1000, 0, 250, 440, 500, 880, 2000, TONES_END];
    /// ```
    /// Using `tones()`, with the data in PROGMEM, is normally a better
    /// choice. The only reason to use tonesInRAM() would be if dynamically
    /// altering the contents of the array is required.
    pub fn tones_in_ram(&self, tones: *mut u32) {
        unsafe { sound_tones_in_ram(tones) }
    }
    /// Set the volume to always normal, always high, or tone controlled.
    ///
    /// One of the following values should be used:
    ///
    /// - `VOLUME_IN_TONE` The volume of each tone will be specified in the tone
    ///    itself.
    /// - `VOLUME_ALWAYS_NORMAL` All tones will play at the normal volume level.
    /// - `VOLUME_ALWAYS_HIGH` All tones will play at the high volume level.
    pub fn volume_mode(&self, mode: u8) {
        unsafe { sound_volume_mode(mode) }
    }
}
extern "C" {
    #[link_name = "sound_tone"]
    fn sound_tone(frequency: c_uint, duration: c_ulong);
    #[link_name = "sound_tone2"]
    fn sound_tone2(frequency1: c_uint, duration1: c_ulong, frequency2: c_uint, duration2: c_ulong);
    #[link_name = "sound_tone3"]
    fn sound_tone3(
        frequency1: c_uint,
        duration1: c_ulong,
        frequency2: c_uint,
        duration2: c_ulong,
        frequency3: c_uint,
        duration3: c_ulong,
    );
    #[link_name = "sound_tones"]
    fn sound_tones(tones: *const c_uint);
    #[link_name = "sound_no_tone"]
    fn sound_no_tone();
    #[link_name = "sound_playing"]
    fn sound_playing() -> bool;
    #[link_name = "sound_tones_in_ram"]
    fn sound_tones_in_ram(tones: *mut c_ulong);
    #[link_name = "sound_volume_mode"]
    fn sound_volume_mode(mode: c_uchar);
}